import os
import sys
from fnmatch import fnmatchcase
from distutils.util import convert_path
standard_exclude = ('*.py', '*.pyc', '*$py.class', '*~', '.*', '*.bak')
standard_exclude_directories = ('.*', 'CVS', '_darcs', './build', './dist', 'EGG-INFO', '*.egg-info')

def find_package_data(where = '.', package = '', exclude = standard_exclude, exclude_directories = standard_exclude_directories, only_in_packages = True, show_ignored = False):
    out = {}
    stack = [(convert_path(where),
      '',
      package,
      only_in_packages)]
    while stack:
        (where, prefix, package, only_in_packages,) = stack.pop(0)
        for name in os.listdir(where):
            fn = os.path.join(where, name)
            if os.path.isdir(fn):
                bad_name = False
                for pattern in exclude_directories:
                    if (fnmatchcase(name, pattern) or (fn.lower() == pattern.lower())):
                        bad_name = True
                        if show_ignored:
                            print >> sys.stderr, ('Directory %s ignored by pattern %s' % (fn, pattern))
                        break

                if bad_name:
                    pass
            if (os.path.isfile(os.path.join(fn, '__init__.py')) and (not prefix)):
                if not package:
                    new_package = name
                else:
                    new_package = ((package + '.') + name)
                stack.append((fn,
                 '',
                 new_package,
                 False))
            else:
                stack.append((fn,
                 ((prefix + name) + '/'),
                 package,
                 only_in_packages))
                continue
                if (package or (not only_in_packages)):
                    bad_name = False
                    for pattern in exclude:
                        if (fnmatchcase(name, pattern) or (fn.lower() == pattern.lower())):
                            bad_name = True
                            if show_ignored:
                                print >> sys.stderr, ('File %s ignored by pattern %s' % (fn, pattern))
                            break

                    if bad_name:
                        pass
                out.setdefault(package, []).append((prefix + name))
                continue


    return out


if (__name__ == '__main__'):
    import pprint
    pprint.pprint(find_package_data(show_ignored=True))

